/**
 * SD模板数据验证工具
 */

import { 
  SDTemplate, 
  Txt2ImgTemplate, 
  Img2ImgTemplate, 
  PostprocessTemplate,
  TemplateType,
  ValidationResult,
  ValidationError
} from '@/types/templates';

// 必填字段验证（包含id，用于更新操作）
const requiredFields = {
  txt2img: [
    'id', 'name', 'description', 'image', 'base_model', 'prompt', 
    'negative_prompt', 'sampler_name', 'steps', 'cfg_scale', 'width', 'height', 'seed'
  ],
  img2img: [
    'id', 'name', 'description', 'image', 'base_model', 'prompt', 
    'negative_prompt', 'sampler_name', 'steps', 'cfg_scale', 'width', 'height', 'seed', 'denoising_strength'
  ],
  postprocess: [
    'id', 'name', 'description', 'image', 'resize_mode', 'upscaling_resize',
    'upscaling_resize_w', 'upscaling_resize_h', 'upscaling_crop', 'upscaler_1', 'upscaler_2', 'extras_upscaler_2_visibility'
  ]
};

// 创建时的必填字段验证（不包含id）
const requiredFieldsForCreate = {
  txt2img: [
    'name', 'description', 'image', 'base_model', 'prompt', 
    'negative_prompt', 'sampler_name', 'steps', 'cfg_scale', 'width', 'height', 'seed'
  ],
  img2img: [
    'name', 'description', 'image', 'base_model', 'prompt', 
    'negative_prompt', 'sampler_name', 'steps', 'cfg_scale', 'width', 'height', 'seed', 'denoising_strength'
  ],
  postprocess: [
    'name', 'description', 'image', 'resize_mode', 'upscaling_resize',
    'upscaling_resize_w', 'upscaling_resize_h', 'upscaling_crop', 'upscaler_1', 'upscaler_2', 'extras_upscaler_2_visibility'
  ]
};

// 数值范围验证
const numericRanges = {
  steps: { min: 1, max: 150 },
  cfg_scale: { min: 1, max: 30 },
  width: { min: 64, max: 2048 },
  height: { min: 64, max: 2048 },
  lora_weight: { min: 0, max: 2 },
  clip_skip: { min: 1, max: 12 },
  denoising_strength: { min: 0, max: 1 },
  upscaling_resize: { min: 1, max: 8 },
  upscaling_resize_w: { min: 64, max: 4096 },
  upscaling_resize_h: { min: 64, max: 4096 },
  extras_upscaler_2_visibility: { min: 0, max: 1 }
};

/**
 * 验证模板数据（用于更新操作，包含id验证）
 */
export function validateTemplate(template: Partial<SDTemplate>): ValidationResult {
  const errors: ValidationError[] = [];
  
  // 检查类型
  if (!template.type || !Object.values(TemplateType).includes(template.type as TemplateType)) {
    errors.push({ field: 'type', message: '模板类型必须是 txt2img、img2img 或 postprocess' });
    return { isValid: false, errors };
  }

  const templateType = template.type as TemplateType;
  const required = requiredFields[templateType];

  // 检查必填字段
  for (const field of required) {
    if (!(field in template) || template[field as keyof SDTemplate] === undefined || template[field as keyof SDTemplate] === null || template[field as keyof SDTemplate] === '') {
      errors.push({ field, message: `${field} 是必填字段` });
    }
  }

  return validateCommonFields(template, templateType, errors);
}

/**
 * 验证模板数据（用于创建操作，不包含id验证）
 */
export function validateTemplateForCreate(template: Partial<SDTemplate>): ValidationResult {
  const errors: ValidationError[] = [];
  
  // 检查类型
  if (!template.type || !Object.values(TemplateType).includes(template.type as TemplateType)) {
    errors.push({ field: 'type', message: '模板类型必须是 txt2img、img2img 或 postprocess' });
    return { isValid: false, errors };
  }

  const templateType = template.type as TemplateType;
  const required = requiredFieldsForCreate[templateType];

  // 检查必填字段（不包含id）
  for (const field of required) {
    if (!(field in template) || template[field as keyof SDTemplate] === undefined || template[field as keyof SDTemplate] === null || template[field as keyof SDTemplate] === '') {
      errors.push({ field, message: `${field} 是必填字段` });
    }
  }

  return validateCommonFields(template, templateType, errors);
}

/**
 * 通用字段验证逻辑
 */
function validateCommonFields(template: Partial<SDTemplate>, templateType: TemplateType, errors: ValidationError[]): ValidationResult {

  // 数值范围验证
  for (const [field, range] of Object.entries(numericRanges)) {
    const value = (template as any)[field];
    if (value !== undefined && value !== null) {
      if (typeof value !== 'number' || value < range.min || value > range.max) {
        errors.push({ 
          field, 
          message: `${field} 必须是 ${range.min} 到 ${range.max} 之间的数字` 
        });
      }
    }
  }

  // ID格式验证
  if (template.id && !/^[a-zA-Z0-9_-]+$/.test(template.id)) {
    errors.push({ field: 'id', message: 'ID只能包含字母、数字、下划线和连字符' });
  }

  // 图片路径验证
  if (template.image && !template.image.startsWith('/')) {
    errors.push({ field: 'image', message: '图片路径必须以 / 开头' });
  }

  // 特定类型验证
  if (templateType === TemplateType.TXT2IMG || templateType === TemplateType.IMG2IMG) {
    const imgTemplate = template as Partial<Txt2ImgTemplate | Img2ImgTemplate>;
    // 提示词长度验证
    if (imgTemplate.prompt && imgTemplate.prompt.length > 2000) {
      errors.push({ field: 'prompt', message: '提示词长度不能超过2000字符' });
    }
    if (imgTemplate.negative_prompt && imgTemplate.negative_prompt.length > 2000) {
      errors.push({ field: 'negative_prompt', message: '负面提示词长度不能超过2000字符' });
    }
  }

  if (templateType === TemplateType.POSTPROCESS) {
    // 后处理特定验证
    const postTemplate = template as PostprocessTemplate;
    if (postTemplate.upscaling_crop !== undefined && typeof postTemplate.upscaling_crop !== 'boolean') {
      errors.push({ field: 'upscaling_crop', message: 'upscaling_crop 必须是布尔值' });
    }
  }

  return {
    isValid: errors.length === 0,
    errors
  };
}

/**
 * 验证模板ID是否唯一
 */
export function validateUniqueId(id: string, existingIds: string[]): boolean {
  return !existingIds.includes(id);
}

/**
 * 清理和标准化模板数据
 */
export function sanitizeTemplate(template: Partial<SDTemplate>): Partial<SDTemplate> {
  const sanitized = { ...template };
  
  // 清理字符串字段
  if (sanitized.name) sanitized.name = sanitized.name.trim();
  if (sanitized.description) sanitized.description = sanitized.description.trim();
  if ((sanitized as any).prompt) (sanitized as any).prompt = (sanitized as any).prompt.trim();
  if ((sanitized as any).negative_prompt) (sanitized as any).negative_prompt = (sanitized as any).negative_prompt.trim();
  
  // 确保数值字段是数字类型
  const numericFields = ['steps', 'cfg_scale', 'width', 'height', 'seed', 'lora_weight', 'clip_skip', 'denoising_strength'];
  for (const field of numericFields) {
    const value = (sanitized as any)[field];
    if (value !== undefined && value !== null) {
      const numValue = Number(value);
      if (!isNaN(numValue)) {
        (sanitized as any)[field] = numValue;
      }
    }
  }
  
  return sanitized;
}

/**
 * 生成唯一ID
 */
export function generateUniqueId(name: string, existingIds: string[]): string {
  // 基于名称生成基础ID
  let baseId = name
    .toLowerCase()
    .replace(/[^a-z0-9\u4e00-\u9fa5]/g, '_')
    .replace(/_+/g, '_')
    .replace(/^_|_$/g, '')
    .substring(0, 30);
  
  if (!baseId) {
    baseId = 'template';
  }
  
  // 确保唯一性
  let uniqueId = baseId;
  let counter = 1;
  
  while (existingIds.includes(uniqueId)) {
    uniqueId = `${baseId}_${counter}`;
    counter++;
  }
  
  return uniqueId;
}